package com.atguigu.lease.web.app.custom.interceptor;

import com.atguigu.lease.common.context.LoginUser;
import com.atguigu.lease.common.context.LoginUserContext;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * Package: com.atguigu.lease.web.admin.custom.interceptor
 *
 * @Description:
 * @Author xiongkunYang
 * @Create 2025/4/28 11:00
 */
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前进行拦截处理
     *
     * @param request  请求对象，用于获取请求头中的token信息
     * @param response 响应对象，可用于向客户端返回数据
     * @param handler  处理请求的对象，此处未使用
     * @return 总是返回true，表示放行请求，除非抛出异常
     * @throws LeaseException 当token不存在或用户信息无效时抛出的自定义异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        // 从请求头中获取token
        String token = request.getHeader("access_token");
        // 如果token为空，则抛出异常，提示需要登录验证
        if (token == null) {
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_AUTH);
        }
        // 解析token，获取其中的用户信息
        Claims claims = JwtUtil.parseToken(token);
        // 获取用户的ID
        Long userId = claims.get("userId", Long.class);
        // 获取用户的用户名
        String username = claims.get("username", String.class);
        // 如果用户ID或用户名为空，则抛出异常，提示token无效
        if (userId == null || username == null) {
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }
        // 将用户信息设置到登录用户上下文中，供后续使用
        LoginUserContext.setLoginUser(new LoginUser(userId, username));
        // 放行请求
        return true;
    }

    @Override
    public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) {
        LoginUserContext.clear();
    }
}